/**
 * Copyright 2020 The Magma Authors.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#pragma once

#include <stdint.h>

namespace magma {
enum DiameterResultCode {
  DIAMETER_MULTI_ROUND_AUTH = 1001,

  DIAMETER_SUCCESS                     = 2001,
  DIAMETER_LIMITED_SUCCESS             = 2002,
  DIAMETER_FIRST_REGISTRATION          = 2003,
  DIAMETER_HSS_SERVER_NAME_NOT_STORED  = 2004,
  DIAMETER_UNREGISTERED_SERVICE        = 2005,
  DIAMETER_SERVER_NAME_NOT_STORED      = 2006,
  DIAMETER_SERVER_SELECTION            = 2007,
  DIAMETER_AUTH_SENT_SERVER_NOT_STORED = 2008,
  DIAMETER_SUCCESS_RELOCATE_HA         = 2009,
  DIAMETER_CONTEXT_DELETION_INDICATION = 2021,

  DIAMETER_COMMAND_UNSUPPORTED       = 3001,
  DIAMETER_UNABLE_TO_DELIVER         = 3002,
  DIAMETER_REALM_NOT_SERVED          = 3003,
  DIAMETER_TOO_BUSY                  = 3004,
  DIAMETER_LOOP_DETECTED             = 3005,
  DIAMETER_REDIRECT_INDICATION       = 3006,
  DIAMETER_APPLICATION_UNSUPPORTED   = 3007,
  DIAMETER_INVALID_HDR_BITS          = 3008,
  DIAMETER_INVALID_AVP_BITS          = 3009,
  DIAMETER_UNKNOWN_PEER              = 3010,
  DIAMETER_REALM_REDIRECT_INDICATION = 3011,

  // Transient Failures
  DIAMETER_AUTHENTICATION_REJECTED       = 4001,
  DIAMETER_OUT_OF_SPACE                  = 4002,
  DIAMETER_ELECTION_LOST                 = 4003,
  DIAMETER_4004                          = 4004,
  DIAMETER_MIP_REPLY_FAILURE             = 4005,
  DIAMETER_HA_NOT_AVAILABLE              = 4006,
  DIAMETER_BAD_KEY                       = 4007,
  DIAMETER_MIP_FILTER_NOT_SUPPORTED      = 4008,
  DIAMETER_4009                          = 4009,
  DIAMETER_END_USER_SERVICE_DENIED       = 4010,
  DIAMETER_CREDIT_CONTROL_NOT_APPLICABLE = 4011,
  DIAMETER_CREDIT_LIMIT_REACHED          = 4012,
  DIAMETER_USER_NAME_REQUIRED            = 4013,
  DIAMETER_RESOURCE_FAILURE              = 4014,
  DIAMETER_USER_DATA_NOT_AVAILABLE       = 4100,
  DIAMETER_PRIOR_UPDATE_IN_PROGRESS      = 4101,
  DIAMETER_ERROR_OUT_OF_RESOURCES        = 4121,
  DIAMETER_PCC_BEARER_EVENT              = 4141,
  DIAMETER_BEARER_EVENT,
  DIAMETER_AN_GW_FAILED,
  DIAMETER_PENDING_TRANSACTION,
  DIAMETER_AUTHENTICATION_DATA_UNAVAILABLE = 4181,
  DIAMETER_CAMEL_SUBSCRIPTION_PRESENT,
  DIAMETER_ERROR_ABSENT_USER = 4201,
  DIAMETER_UNREACHABLE_USER  = 4221,
  DIAMETER_ERROR_SUSPENDED_USER,
  DIAMETER_ERROR_DETACHED_USER,
  DIAMETER_ERROR_POSITIONING_DENIED,
  DIAMETER_ERROR_POSITIONING_FAILED,
  DIAMETER_UNKNOWN_UNREACHABLE_LCS_CLIENT,
  DIAMETER_NO_AVAILABLE_POLICY_COUNTERS       = 4241,
  DIAMETER_SERVICE_TEMPORARILY_NOT_AUTHORIZED = 4261,

  // Permanent Failures
  DIAMETER_AVP_UNSUPPORTED               = 5001,
  DIAMETER_UNKNOWN_SESSION_ID            = 5002,
  DIAMETER_AUTHORIZATION_REJECTED        = 5003,
  DIAMETER_INVALID_AVP_VALUE             = 5004,
  DIAMETER_MISSING_AVP                   = 5005,
  DIAMETER_RESOURCES_EXCEEDED            = 5006,
  DIAMETER_CONTRADICTING_AVPS            = 5007,
  DIAMETER_AVP_NOT_ALLOWED               = 5008,
  DIAMETER_AVP_OCCURS_TOO_MANY_TIMES     = 5009,
  DIAMETER_NO_COMMON_APPLICATION         = 5010,
  DIAMETER_UNSUPPORTED_VERSION           = 5011,
  DIAMETER_UNABLE_TO_COMPLY              = 5012,
  DIAMETER_INVALID_BIT_IN_HEADER         = 5013,
  DIAMETER_INVALID_AVP_LENGTH            = 5014,
  DIAMETER_INVALID_MESSAGE_LENGTH        = 5015,
  DIAMETER_INVALID_AVP_BIT_COMBO         = 5016,
  DIAMETER_NO_COMMON_SECURITY            = 5017,
  DIAMETER_RADIUS_AVP_UNTRANSLATABLE     = 5018,
  DIAMETER_NO_FOREIGN_HA_SERVICE         = 5024,
  DIAMETER_END_TO_END_MIP_KEY_ENCRYPTION = 5025,
  DIAMETER_USER_UNKNOWN                  = 5030,
  DIAMETER_RATING_FAILED,
  DIAMETER_SIP_USER_UNKNOWN,
  DIAMETER_IDENTITIES_DONT_MATCH,
  DIAMETER_IDENTITY_NOT_REGISTERED,
  DIAMETER_ROAMING_NOT_ALLOWED,
  DIAMETER_IDENTITY_ALREADY_REGISTERED,
  DIAMETER_AUTH_SCHEME_NOT_SUPPORTED,
  DIAMETER_IN_ASSIGNMENT_TYPE,
  DIAMETER_TOO_MUCH_DATA,
  DIAMETER_NOT_SUPPORTED_USER_DATA,
  DIAMETER_NO_WLAN_SUBSCRIPTION,
  DIAMETER_W_APN_UNUSED_BY_USER,
  DIAMETER_NO_ACCESS_INDEPENDENT_SUBSCRIPTION,
  DIAMETER_USER_NO_W_APN_SUBSCRIPTION,
  DIAMETER_UNSUITABLE_NETWORK,
  DIAMETER_EAP_CODE_UNKNOWN            = 5048,
  DIAMETER_INVALID_SERVICE_INFORMATION = 5061,
  DIAMETER_FILTER_RESTRICTIONS,
  DIAMETER_REQUESTED_SERVICE_NOT_AUTHORIZED,
  DIAMETER_DUPLICATED_AF_SESSION,
  DIAMETER_CAN_SESSION_NOT_AVAILABLE,
  DIAMETER_NON_EMERGENCY_SESSION,
  DIAMETER_UNAUTHORIZED_SPONSORED_DATA_CONNECTIVITY,
  DIAMETER_TEMPORARY_NETWORK_FAILURE,
  DIAMETER_USER_DATA_NOT_RECOGNIZED = 5100,
  DIAMETER_OPERATION_NOT_ALLOWED,
  DIAMETER_DATA_CANNOT_BE_READ,
  DIAMETER_USER_DATA_CANNOT_BE_MODIFIED,
  DIAMETER_DATA_CANNOT_BE_NOTIFIED,
  DIAMETER_TRANSPARENT_DATA_OUT_OF_SYNC,
  DIAMETER_ERROR_SUBS_DATA_ABSENT,
  DIAMETER_NO_SUBSCRIPTION_TO_DATA,
  DIAMETER_DSAI_NOT_AVAILABLE,
  DIAMETER_ERROR_START_INDICATION = 5120,
  DIAMETER_ERROR_STOP_INDICATION,
  DIAMETER_UNKNOWN_MBMS_BEARER_SERVICE,
  DIAMETER_ERROR_SERVICE_AREA,
  DIAMETER_BEARER_NOT_AUTHORIZED,
  DIAMETER_ERROR_INITIAL_PARAMETERS = 5140,
  DIAMETER_ERROR_TRIGGER_EVENT,
  DIAMETER_PCC_RULE_EVENT,
  DIAMETER_TRAFFIC_MAPPING_INFO_REJECTED,
  DIAMETER_QOS_RULE_EVENT,
  DIAMETER_CONFLICTING_REQUEST,
  DIAMETER_ADC_RULE_EVENT,
  DIAMETER_NBIFOM_NOT_AUTHORIZED,
  DIAMETER_ERROR_IMPI_UNKNOWN = 5401,
  DIAMETER_ERROR_NOT_AUTHORIZED,
  DIAMETER_TRANSACTION_IDENTIFIER_INVALID,
  DIAMETER_UNKNOWN_EPS_SUBSCRIPTION,
  DIAMETER_RAT_NOT_ALLOWED,
  DIAMETER_EQUIPMENT_UNKNOWN,
  DIAMETER_UNKNOWN_SERVING_NODE,
  DIAMETER_NO_NON_3GPP_SUBSCRIPTION = 5450,
  DIAMETER_USER_NO_APN_SUBSCRIPTION,
  DIAMETER_RAT_TYPE_NOT_ALLOWED,
  DIAMETER_LATE_OVERLAPPING_REQUEST,
  DIAMETER_TIMED_OUT_REQUEST,
  DIAMETER_ERROR_SUBSESSION = 5470,
  DIAMETER_V2X_NOT_ALLOWED  = 5691,
};

class DiameterCodeHandler {
 public:
  /** Diameter code of form 5xxx marks a permanent failure
   * @param code
   * @return
   */
  static bool is_permanent_failure(const uint32_t code);

  /** Individual messages included in terminator_codes list will trigger a
   * session termination. This function is run before is_permanent_failure
   * @param code
   * @return
   */
  static bool is_terminator_failure(const uint32_t code);

  /** Diameter code of form 4xxx marks a transient failure. Normally used after
   * running is_terminator_failure
   * @param code
   * @return
   */
  static bool is_transient_failure(const uint32_t code);
};
}  // namespace magma
